#ifndef CNC_UI_MANAGER_IMPLEMENTATION_H
#define CNC_UI_MANAGER_IMPLEMENTATION_H

// provided interfaces
#include "taskctl.h"
#include "uiservs.h"
// required interface
#include "enventities.h"
#include "millpdata.h"
#include "globaldata.h"
#include "progmgr.h"
// basic component model
#include <bcm/bcm.h>

namespace cnc {

	namespace ui {

		class ManagerImpl
		{
		protected:
			bcm::GetComponentResult result_;
			bcm::Component *component_;
			cnc::base::TaskControl *taskCtl_;
			Services *srv_;
			ManagerImpl() : result_(bcm::GC_OK), taskCtl_(0), srv_(0)
			{
				bcm::ComponentManager &compMgr = bcm::ComponentManager::instance();
				switch (compMgr.loadComponent(TEXT("win32desktop.dll"))) {
				case bcm::LC_NODLL:
				case bcm::LC_NOCOMPONENT:
				case bcm::LC_ALREADYUSED:
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
				switch (compMgr.getComponent("w32desk", &component_)) {
				case bcm::GC_UNREGISTERED:
				case bcm::GC_NOCOMPONENT:
				case bcm::GC_INCOMPLETE:
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
				bcm::Interface *iface;
				iface = component_->getInterface("taskctl");
				if (iface == 0) {
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
				taskCtl_ = dynamic_cast<cnc::base::TaskControl *>(iface);
				if (taskCtl_ == 0) {
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
				iface = component_->getInterface("uiservs");
				if (iface == 0) {
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
				srv_ = dynamic_cast<Services *>(iface);
				if (srv_ == 0) {
					result_ = bcm::GC_INCOMPLETE;
					return;
				}
			}
			void operator=(ManagerImpl &);
		public:
			cnc::base::TaskControl *getTaskControl()
			{
				return taskCtl_;
			}
			Services *getServices()
			{
				return srv_;
			}
			void setEnvironmentEntities(cnc::rtl::EnvironmentEntities *env)
			{
				component_->setInterface(env);
			}
			void setMillPersistentData(cnc::base::MillPersistentData *millpdata)
			{
				component_->setInterface(millpdata);
			}
			void setGlobalData(cnc::base::GlobalData *gd)
			{
				component_->setInterface(gd);
			}
			void setProgramManager(cnc::compiler::ProgramManager *pm)
			{
				component_->setInterface(pm);
			}
		};

	} // namespace ui

} // namespace cnc

#endif
